/*****************************************************************************
 *  ENTROPY - emerging network to reduce orwellian potency yield
 *
 *  Copyright (C) 2002 Juergen Buchmueller <pullmoll@stop1984.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software Foundation,
 *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 *	$Id: key.h,v 1.3 2005/07/12 23:19:26 pullmoll Exp $
 *****************************************************************************/
#ifndef	_key_h_
#define	_key_h_

#include "osd.h"
#include "sha1.h"
#include "ek5.h"
#include "base64.h"

/* number of base64 digits for the first part of a key */
#define	KEY1SIZE	(((SHA1SIZE+1+2)*8+5)/6)
/* number of base64 digits for the second part of a key */
#define	KEY2SIZE	((EK5SIZE*8+5)/6)

typedef struct chkey_s {
	sha1_digest_t sha1;		/* 20 bytes */
	uint8_t log2size;		/*  1 byte  */
	uint8_t type[2];		/*  2 bytes */
	ek5_digest_t ek5;		/* 16 bytes */
	uint8_t padding;		/*  1 byte */
							/*  = total 40 bytes */
}	chkey_t;

/* it should be sufficient to compare the key SHA1 hash */
#define	CMPSIZE	(SHA1SIZE)
#define	keycmp(k1,k2)	memcmp((k1)->sha1.digest,(k2)->sha1.digest,CMPSIZE)

typedef struct key_state_s {
	size_t size;
	uint32_t type;
	sha1_state_t ss;
	ek5_state_t es;
}	key_state_t;

#define	K_KSK	0x6407		/* key is a key signed key */
#define	K_CHK	0x1af9		/* key is a content hash key */
#define	K_SSK_P	0x0203		/* key is a public sub space key */
#define	K_SSK_S	0x0202		/* key is a secret sub space key */
#define	K_BIT	0x0000		/* key is an internal key */
#define	MSB(n)	(uint8_t)((n)>>8)
#define	LSB(n)	(uint8_t)(n)

typedef struct dragon_s {
	uint32_t d[32];
	uint64_t m;
	uint32_t i;
} dragon_t;
#ifdef	__cplusplus
extern "C" {
#endif

uint8_t log2size(size_t size);

/*
 * Return the routing key for a SHA1 digest
 */
static inline uint8_t keyroute(const sha1_digest_t *pd)
{
	uint32_t sum, i;
	for (sum = 0, i = 0; i < SHA1SIZE; i++)
		sum += pd->digest[i];
	sum = sum + (sum >> 8);
	return (sum + (sum >> 4)) & 0x0f;
}

int key_chk(chkey_t *key, const void *buff, size_t size);
const char *key_str(const chkey_t *key);
const char *key_long(const chkey_t *key);
const char *key_short(const chkey_t *key);
int str_key(chkey_t *key, const char *src);
int str_ssk(chkey_t *key, const char *src);

int key_ssk_pub_from_priv(chkey_t *pub, const chkey_t *priv);
int key_svk_pair_create(chkey_t *pub, chkey_t *priv);

dragon_t *key_setup(uint8_t *key);
int key_output(dragon_t *ctx, void *buff, size_t size);
int key_destroy(dragon_t *ctx);

#define	KEY_CRYPT_GZ	1
int key_crypt(uint8_t *key, void *buff, size_t size, int flags);

#ifdef	__cplusplus
}
#endif
#endif	/* !defined(_key_h_) */
